package com.zzh.partnersys.utils;

/**
 * @author zzh
 * @version 1.0
 */

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.util.CollectionUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 	图片合成(仿微信群聊头像)
 *
 */
public class ImageUtils {

    /**
     * 	图片格式：JPG
     */
    private static final String PICTURE_FORMAT_PNG = "jpg";

    private ImageUtils() {
    }

    /**
     * 	画板的高
     */
    private static final Integer PICTURE_HEIGHT = 112;

    /**
     * 	画板的宽
     */
    private static final Integer PICTURE_WIDTH = 112;

    /**
     * 	生成组合头像
     *
     * @param urls
     *      	用户图像路径(绝对路径)
     * @param outImgPath
     * 			 新图片路�?绝对路径)
     * @throws IOException
     */
    public static String getCombinationOfHead(List<String> urls, String outImgPath) throws IOException {
        if (CollectionUtils.isEmpty(urls)) {
            return null;
        }
        List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();
        // 压缩图片所有的图片生成尺寸
        int imgH = 32;// 图片的高
        int imgW = 32;// 图片的宽
        if (urls.size() <= 4) {
            imgH = imgW = 50;
        }
        boolean flag = false;
        for (int i = 0; i < urls.size(); i++) {
            if (urls.get(i)!= null &&!urls.get(i).isEmpty()) {
                BufferedImage image = getImageFromUrl(urls.get(i));
                if (image!= null) {
                    flag = true;
                    bufferedImages.add(ImageUtils.resizeImage(image, imgH, imgW, false));
                }
            }
        }
        if (!flag) {
            return null;
        }
        // BufferedImage.TYPE_INT_RGB可以自己定义可查看API
        BufferedImage outImage = new BufferedImage(PICTURE_WIDTH, PICTURE_HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 生成画布
        Graphics g = outImage.getGraphics();
        Graphics2D g2d = (Graphics2D) g;
        // 设置背景�?
        g2d.setBackground(new Color(231, 231, 231));
        // 通过使用当前绘图表面的背景色进行填充来清除指定的矩形�?
        g2d.clearRect(0, 0, PICTURE_WIDTH, PICTURE_HEIGHT);
        // 开始拼�?根据图片的数量判断该生成那种样式的组合头�?
        layoutImage(g2d, bufferedImages, imgW);
        String imgName = new Date().getTime() + "_" + new Random().nextInt(120000) + "."
                + PICTURE_FORMAT_PNG.toLowerCase();
        if (!outImgPath.endsWith("/") && !outImgPath.endsWith("\\")) {
            outImgPath += "/";
        }
        File file = new File(outImgPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        ImageIO.write(outImage, PICTURE_FORMAT_PNG, new File(outImgPath + imgName));
        return imgName;
    }

    /**
     * 	生成组合头像
     * @param urls 用户图像路径(绝对路径)
     * @throws IOException
     * @Return BufferedImage
     */
    public static BufferedImage getCombinationOfHeadToBufferedImages(List<String> urls) throws IOException {
        if (CollectionUtils.isEmpty(urls)) {
            return null;
        }
        List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();
        // 压缩图片所有的图片生成尺寸
        int imgH = 32;// 图片的高
        int imgW = 32;// 图片的宽
        if (urls.size() <= 4) {
            imgH = imgW = 50;
        }
        boolean flag = false;
        for (int i = 0; i < urls.size(); i++) {
            if (urls.get(i)!= null &&!urls.get(i).isEmpty()) {
                BufferedImage image = getImageFromUrl(urls.get(i));
                if (image!= null) {
                    flag = true;
                    bufferedImages.add(ImageUtils.resizeImage(image, imgH, imgW, false));
                }
            }
        }
        if (!flag) {
            return null;
        }
        // BufferedImage.TYPE_INT_RGB可以自己定义可查看API
        BufferedImage outImage = new BufferedImage(PICTURE_WIDTH, PICTURE_HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 生成画布
        Graphics g = outImage.getGraphics();
        Graphics2D g2d = (Graphics2D) g;
        // 设置背景�?
        g2d.setBackground(new Color(231, 231, 231));
        // 通过使用当前绘图表面的背景色进行填充来清除指定的矩形�?
        g2d.clearRect(0, 0, PICTURE_WIDTH, PICTURE_HEIGHT);
        // 开始拼�?根据图片的数量判断该生成那种样式的组合头�?
        layoutImage(g2d, bufferedImages, imgW);
        return outImage;
    }


    /**
     * �?URL 获取图片
     *
     * @param url 图片 URL
     * @return 图片�?BufferedImage 对象，如果获取失败返�?null
     */
    private static BufferedImage getImageFromUrl(String url) {
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            InputStream inputStream = response.getEntity().getContent();
            return ImageIO.read(inputStream);
        } catch (IOException  e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 图片布局生成组合图片
     * @param g2d 画布
     * @param bufferedImages 图片
     * @param imgW 图片的宽
     */
    private static void layoutImage(Graphics2D g2d, List<BufferedImage> bufferedImages, int imgW) {
        int j = 1;
        int k = 1;
        for (int i = 1; i <= bufferedImages.size(); i++) {
            if (bufferedImages.size() == 9) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 4, null);
                } else if (i >= 4 && i <= 6) {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (k - 1) + 4 * k, 4 * 2 + imgW, null);
                    ++k;
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 4 * 3 + imgW * 2, null);
                    j++;
                }
            } else if (bufferedImages.size() == 8) {
                if (i <= 2) {
                    g2d.drawImage(bufferedImages.get(i - 1), 18 + imgW * (i - 1) + 4 * i, 4, null);
                } else if (i >= 3 && i <= 5) {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (k - 1) + 4 * k, 4 * 2 + imgW, null);
                    ++k;
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 4 * 3 + imgW * 2, null);
                    j++;
                }
            } else if (bufferedImages.size() == 7) {
                if (i <= 1) {
                    g2d.drawImage(bufferedImages.get(i - 1), 36 + imgW * (i - 1) + 4 * i, 4, null);
                } else if (i >= 2 && i <= 4) {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (k - 1) + 4 * k, 4 * 2 + imgW, null);
                    ++k;
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 4 * 3 + imgW * 2, null);
                    j++;
                }
            } else if (bufferedImages.size() == 6) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 22, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
                    j++;
                }
            } else if (bufferedImages.size() == 5) {
                if (i <= 2) {
                    g2d.drawImage(bufferedImages.get(i - 1), 18 + imgW * (i - 1) + 4 * i, 22, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
                    j++;
                }
            } else if (bufferedImages.size() == 4) {
                if (i <= 2) {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 4, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
                    j++;
                }
            } else if (bufferedImages.size() == 3) {
                if (i <= 1) {
                    g2d.drawImage(bufferedImages.get(i - 1), 31, 4, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), imgW * (j - 1) + 4 * j, 58, null);
                    j++;
                }
            } else if (bufferedImages.size() == 2) {
                g2d.drawImage(bufferedImages.get(i - 1), imgW * (i - 1) + 4 * i, 31, null);
            } else if (bufferedImages.size() == 1) {
                g2d.drawImage(bufferedImages.get(i - 1), 31, 31, null);
            }
            // 需要改变颜色的话在这里绘上颜色。可能会用到AlphaComposite�?
        }
    }

    /**
     * 	图片缩放
     *
     * @param image
     *            	图片
     * @param height
     *            	高度
     * @param width
     *            	宽度
     * @param flag
     *            	比例不对时是否需要补�?
     */
    @SuppressWarnings("removal")
    public static BufferedImage resizeImage(BufferedImage image, int height, int width, boolean flag) {
        try {
            double ratio = 0; // 缩放比例
            Image itemp = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            // 计算比例
            if ((image.getHeight() > height) || (image.getWidth() > width)) {
                if (image.getHeight() > image.getWidth()) {
                    ratio = (new Integer(height)).doubleValue() / image.getHeight();
                } else {
                    ratio = (new Integer(width)).doubleValue() / image.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
                itemp = op.filter(image, null);
            }
            if (flag) {
                BufferedImage resizeImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics2D g = resizeImage.createGraphics();
                g.setColor(Color.white);
                g.fillRect(0, 0, width, height);
                if (width == itemp.getWidth(null))
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null),
                            itemp.getHeight(null), Color.white, null);
                else
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null),
                            itemp.getHeight(null), Color.white, null);
                g.dispose();
                itemp = image;
            }
            return (BufferedImage) itemp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 	把图片剪切成圆形图片
     * @param imgPath 原图路径
     * @param outPath 处理后图片输出路�?
     * @return
     * @throws IOException
     */
    public static String cutoutRoundImage(String imgPath, String outPath) throws IOException {
        BufferedImage bufferedImage = ImageIO.read(new File(imgPath));
        // 根据需要是否使�?BufferedImage.TYPE_INT_ARGB
        BufferedImage bufImg = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
        Graphics2D g2 = bufImg.createGraphics();
        g2.setBackground(Color.WHITE);
        g2.fill(new Rectangle(bufImg.getWidth(), bufImg.getHeight()));
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯�?
        g2.drawImage(bufferedImage, 0, 0, null);
        g2.dispose();
        String imgName = new Date().getTime() + "_" + new Random().nextInt(120000) + "."
                + PICTURE_FORMAT_PNG.toLowerCase();
        if (!outPath.endsWith("/") && !outPath.endsWith("\\")) {
            outPath += "/";
        }
        // 输出图片路径
        String imgDir = outPath + imgName;
        try {
            ImageIO.write(bufImg, "jpg", new File(imgDir));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imgDir;
    }


    // �?BufferedImage 转换�?InputStream 的方�?
    public static InputStream bufferedImageToInputStream(BufferedImage image, String format) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, format, os);
        return new ByteArrayInputStream(os.toByteArray());
    }


    public static void main(String[] args) throws IOException {
        List<String> imagePathList = new ArrayList<>();
        //https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg
        //https://profile-avatar.csdnimg.cn/default.jpg!1
        //https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg
        //https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg
        imagePathList.add("https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg");
        imagePathList.add("https://profile-avatar.csdnimg.cn/default.jpg!1");
        imagePathList.add("https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg");
        imagePathList.add("https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg");
//        imagePathList.add("G:\\Quartus9\\个人评价.png");
//        imagePathList.add("G:\\Quartus9\\教育.png");
//        imagePathList.add("G:\\Quartus9\\项目经历-02.png");
        String outPath = "G:\\Quartus9";
//        System.out.println(imageFromUrl);
//        getCombinationOfHead(imagePathList,outPath);


        BufferedImage bfImg = getCombinationOfHeadToBufferedImages(imagePathList);
        InputStream inputStream = bufferedImageToInputStream(bfImg, "png");


    }


}